﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace gChartSharp
{
    /// <summary>
    /// http://code.google.com/apis/chart/#axes_styles
    /// </summary>
    public class AxisStyleParam : IChartParam
    {
        /// <summary>
        /// The name of the API parameter
        /// </summary>
        public string Name { get { return "chxs"; } }


        /// <summary>
        /// A list of AxisStyles
        /// </summary>
        public List<AxisStyle> AxisStyles 
        {
            get { return mAxisStyles ?? (mAxisStyles = new List<AxisStyle>()); }
            set { mAxisStyles = value; }
        }
        private List<AxisStyle> mAxisStyles;


        /// <summary>
        /// The default constructor
        /// </summary>
        public AxisStyleParam() { }


        /// <summary>
        /// Constructor that populates the AxisStyles list
        /// </summary>
        /// <param name="axisStyles"></param>
        public AxisStyleParam(AxisStyle[] axisStyles)
        {
            this.AxisStyles = new List<AxisStyle>();

            foreach (AxisStyle axisStyle in axisStyles)
                this.AxisStyles.Add(axisStyle);
        }


        /// <summary>
        /// Render the API text
        /// </summary>
        /// <returns></returns>
        public string Render()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(String.Format("&{0}=", this.Name));

            foreach (AxisStyle axisStyle in this.AxisStyles)
            {
                // all properties are initialized, go ahead and render the lot
                if (axisStyle.FontSize != null && axisStyle.Alignment != null)
                    sb.Append(String.Format("{0},{1},{2},{3}|", axisStyle.AxisIndex, axisStyle.Color.ToHTML(), axisStyle.FontSize, (int)axisStyle.Alignment));

                // FontSize and Alignment are not set, don't render them
                else if (axisStyle.FontSize == null && axisStyle.Alignment == null)
                    sb.Append(String.Format("{0},{1}|", axisStyle.AxisIndex, axisStyle.Color.ToHTML()));

                // only FontSize has been initialized, render it
                else if (axisStyle.FontSize != null && axisStyle.Alignment == null)
                    sb.Append(String.Format("{0},{1},{2}|", axisStyle.AxisIndex, axisStyle.Color.ToHTML(), axisStyle.FontSize));

                // Alignment has been set but FontSize has not.  We cannot render this without the FontSize
                // as FontSize precedes Alignment in the comma separated list.  Optionally this could be changed
                // to not throw an exception and quietly set the FontSize to some default value
                else if (axisStyle.FontSize == null && axisStyle.Alignment != null)
                    throw new ParamException("Alignment property cannot be set without the FontSize property being set.");
            }

            sb.Remove(sb.ToString().LastIndexOf('|'), 1);

            return sb.ToString();
        }
    }


    public class AxisStyle
    {
        /// <summary>
        /// AxisIndex is the axis index as specified in chxt.
        /// </summary>
        public int AxisIndex { get; set; }


        /// <summary>
        /// Color is an RRGGBB format hexadecimal number.
        /// </summary>
        public Color Color { get; set; }


        /// <summary>
        /// FontSize is optional. If used this specifies the size in pixels.
        /// </summary>
        public int? FontSize { get; set; }


        /// <summary>
        /// Alignment is optional. By default: x-axis labels are centered, left y-axis 
        /// labels are right aligned, right y-axis labels are left aligned. 
        /// To specify alignment, use 0 for centered, -1 for left aligned, and 
        /// 1 for right aligned.
        /// </summary>
        public AxisStyleAlignmentType? Alignment { get; set; }


        public AxisStyle(int axisIndex, Color color, int? fontSize, AxisStyleAlignmentType? alignment)
        {
            this.AxisIndex = axisIndex;
            this.Color = color;
            this.FontSize = fontSize;
            this.Alignment = alignment;
        }


        public AxisStyle(int axisIndex, Color color)
        {
            this.AxisIndex = axisIndex;
            this.Color = color;
        }
    }


    public enum AxisStyleAlignmentType
    {
        Centered = 0,
        LeftAligned = -1,
        RightAligned = 1
    }
}
